<?php

namespace forfun\service;

use forfun\constant\ErrorCode;
use forfun\context\CoreContext;
use forfun\controller\vo\CoupletReplyForm;
use forfun\controller\vo\CoupletReplyModifyForm;
use forfun\repository\AgreeRecordRepository;
use forfun\repository\CoupletReplyRepository;
use forfun\repository\CoupletRepository;
use forfun\repository\entity\AgreeRecord;
use forfun\repository\entity\CoupletReply;
use forfun\repository\UserRepository;
use restphp\biz\PageParam;
use restphp\utils\RestClassUtils;
use Sofical\Restphp\exception\BaException;

class CoupletService {
    /**
     * 获取今日对联.
     * @return mixed|null
     */
    public static function getCoupletToday() {
        $today = date('Y-m-d');
        return self::getCoupletByDate($today);
    }

    public static function getCoupletByDate($day) {
        $coupletRepository = new CoupletRepository();
        $couplet = $coupletRepository->findOne(array(
            'start_date' => $day,
        ));
        if (null !== $couplet) {
            $couplet->setBackgroundImg(ImageService::formatImageUrl($couplet->getBackgroundImg()));
        }
        return $couplet;
    }

    /**
     * 回复对联.
     * @param CoupletReplyForm $coupletReply
     * @return void
     */
    public static function replyCouplet($coupletReply) {
        $coupletRepository = new CoupletRepository();
        $couplet = $coupletRepository->findOneById($coupletReply->getCoupletId());
        if (null == $couplet) {
            throw new BaException(ErrorCode::COUPLET_NOT_EXIST);
        }
        $coupletReplyRepository = new CoupletReplyRepository();
        $repliedNumber = $coupletReplyRepository->count(array(
            'couplet_id' => $coupletReply->getCoupletId(),
        ));
        if ($repliedNumber >= APP_COUPLET_MAX_REPLY_OF_ONE) {
            throw new BaException(ErrorCode::COUPLET_REPLY_OVERFLOW);
        }

        $coupletReplyRepository->pUpdateDB()->startTran();
        $coupletReplyEntity = new CoupletReply();
        $coupletReplyEntity->setCoupletId($coupletReply->getCoupletId());
        $coupletReplyEntity->setUserId(CoreContext::getUser()->getId());
        $coupletReplyEntity->setReplyContent($coupletReply->getContent());
        $coupletReplyEntity->setCreateTime(date('Y-m-d H:i:s'));
        $coupletReplyEntity->setUpdateTime(date('Y-m-d H:i:s'));
        $coupletReplyEntity->setAgreeNumber(0);
        $coupletReplyRepository->save($coupletReplyEntity);
        $couplet->setFollowNumber($couplet->getFollowNumber() + 1);
        $coupletRepository->save($couplet);
        $coupletReplyRepository->pUpdateDB()->commitTran();
    }

    /**
     * 回复列表.
     * @param $coupletId
     * @param $page
     * @return array
     * @throws \restphp\exception\RestException
     */
    public static function getReplyList($coupletId, $page) {
        $coupletReplyRepository = new CoupletReplyRepository();
        $replies = $coupletReplyRepository->select(array(
            'rule' => array(
                'couplet_id' => $coupletId
            ),
            'page_param' => PageParam::getInstance($page, APP_DATA_LIST_PAGE_SIZE),
            'order' => ' order by agree_number desc, id asc'
        ));

        if (empty($replies)) {
            return array();
        }

        $arrRelies = array();
        $arrIds = array();
        $arrUserIds = array();
        foreach ($replies as $reply) {
            $arrReply = RestClassUtils::beanToArr($reply);
            $arrReply['is_owner'] = $reply->getUserId() == CoreContext::getUser()->getId() ? 1 : 0;
            $arrReply['had_agree'] = 0;
            $arrIds[] = $reply->getId();
            $arrRelies[] = $arrReply;
            $arrUserIds[] = $reply->getUserId();
        }

        // 获取是否已点赞.
        $agreeRecordRepository = new AgreeRecordRepository();
        $agreeRecords = $agreeRecordRepository->findAll(array(
            'type'          => AgreeRecord::TYPE_COUPLET_REPLY,
            'user_id'       => CoreContext::getUser()->getId(),
            'record_id'    => array('record_id in (:id)', array('id' => $arrIds))
        ));
        $arrAgreeRecordMap = array();
        foreach ($agreeRecords as $agreeRecord) {
            $arrAgreeRecordMap[$agreeRecord->getRecordId()] = $agreeRecord->getId();
        }

        // 获取用户名.
        $userRepository = new UserRepository();
        $users = $userRepository->findAll(array(
            'id' => array('id in (:id)', array('id' => $arrUserIds))
        ));
        $arrUserNameMap = array();
        foreach ($users as $user) {
            $arrUserNameMap[$user->getId()] = $user->getNickname();
        }

        // 数据组装
        foreach ($arrRelies as &$arrRely) {
            $arrRely['nickname'] = $arrUserNameMap[$arrRely['user_id']];
            $arrRely['had_agree'] = isset($arrAgreeRecordMap[$arrRely['id']]) ? 1 : 0;
        }

        return $arrRelies;
    }

    /**
     * 删除下联.
     * @param $coupletId
     * @param $id
     * @return void
     * @throws BaException
     * @throws \ReflectionException
     */
    public static function deleteReply($coupletId, $id) {
        $coupletRepository = new CoupletRepository();
        $couplet = $coupletRepository->findOneById($coupletId);
        if (null == $couplet) {
            throw new BaException(ErrorCode::COUPLET_NOT_EXIST);
        }
        $coupletReplyRepository = new CoupletReplyRepository();
        $reply = $coupletReplyRepository->findOneById($id);
        if (null == $reply) {
            throw new BaException(ErrorCode::COUPLET_REPLY_NOT_EXIST);
        }
        if ($reply->getUserId() != CoreContext::getUser()->getId()) {
            throw new BaException(ErrorCode::COUPLET_REPLY_NOT_EXIST);
        }
        $coupletReplyRepository->pUpdateDB()->startTran();
        $coupletReplyRepository->deleteById($id);
        $agreeRecordRepository = new AgreeRecordRepository();
        $agreeRecordRepository->deleteByTypeAndRecordId(AgreeRecord::TYPE_COUPLET_REPLY, $id);
        $coupletReplyRepository->pUpdateDB()->commitTran();
    }

    /**
     * @param integer $coupletId
     * @param integer $id
     * @param CoupletReplyModifyForm $coupletReply
     * @return void
     */
    public static function modifyReply($coupletId, $id, $coupletReply) {
        $coupletRepository = new CoupletRepository();
        $couplet = $coupletRepository->findOneById($coupletId);
        if (null == $couplet) {
            throw new BaException(ErrorCode::COUPLET_NOT_EXIST);
        }
        $coupletReplyRepository = new CoupletReplyRepository();
        $reply = $coupletReplyRepository->findOneById($id);
        if (null == $reply) {
            throw new BaException(ErrorCode::COUPLET_REPLY_NOT_EXIST);
        }
        if ($reply->getUserId() != CoreContext::getUser()->getId()) {
            throw new BaException(ErrorCode::COUPLET_REPLY_NOT_EXIST);
        }
        $reply->setReplyContent($coupletReply->getContent());
        $coupletReplyRepository->save($reply);
    }
}